﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BLL.BusinessRules
{
    public class ValidateCompare : BusinessRule
    {
        public string OtherPropertyName { get; set; }
        public ValidationDataType DataType { get; set; }
        public ValidationOperator Operator { get; set; }

        public ValidateCompare(string propertyName, string otherPropertyName, ValidationOperator @operator, ValidationDataType dataType)
            : base(propertyName)
        {
            OtherPropertyName = otherPropertyName;
            DataType = dataType;
            Operator = @operator;

            ErrorMessage = string.Format("{0} must be {1} than {2}", PropertyName, Operator.ToString(), OtherPropertyName);
        }

        public ValidateCompare(string propertyName, string otherPropertyName, string errorMessage, ValidationOperator @operator, ValidationDataType dataType)
            : this(propertyName, otherPropertyName, @operator, dataType)
        {
            ErrorMessage = errorMessage;
        }

        public override bool Validate(BusinessObject businessObject)
        {
            try
            {
                string propValue1 = businessObject.GetType().GetProperty(PropertyName).GetValue(businessObject, null).ToString();
                string propValue2 = businessObject.GetType().GetProperty(PropertyName).GetValue(businessObject, null).ToString();

                switch (DataType)
                {
                    case ValidationDataType.String:
                        int result = string.Compare(propValue1, propValue2, StringComparison.CurrentCulture);
                        switch (Operator)
                        {
                            case ValidationOperator.Equal: return result.Equals(0);
                            case ValidationOperator.NotEqual: return !result.Equals(0);
                            case ValidationOperator.GreaterThan: return (result > 0);
                            case ValidationOperator.GreaterThanEqual: return (result >= 0);
                            case ValidationOperator.LessThan: return (result < 0);
                            case ValidationOperator.LessThanEqual: return (result <= 0);
                        }
                        break;
                    case ValidationDataType.Integer:
                        int iVal1 = int.Parse(propValue1);
                        int iVal2 = int.Parse(propValue2);

                        switch (Operator)
                        {
                            case ValidationOperator.Equal: return iVal1.Equals(iVal2);
                            case ValidationOperator.NotEqual: return !iVal1.Equals(iVal2);
                            case ValidationOperator.GreaterThan: return (iVal1 > iVal2);
                            case ValidationOperator.GreaterThanEqual: return (iVal1 >= iVal2);
                            case ValidationOperator.LessThan: return (iVal1 < iVal2);
                            case ValidationOperator.LessThanEqual: return (iVal1 <= iVal2);
                        }
                        break;
                    case ValidationDataType.Double:
                        double dVal1 = double.Parse(propValue1);
                        double dVal2 = double.Parse(propValue2);

                        switch (Operator)
                        {
                            case ValidationOperator.Equal: return dVal1.Equals(dVal2);
                            case ValidationOperator.NotEqual: return !dVal1.Equals(dVal2);
                            case ValidationOperator.GreaterThan: return (dVal1 > dVal2);
                            case ValidationOperator.GreaterThanEqual: return (dVal1 >= dVal2);
                            case ValidationOperator.LessThan: return (dVal1 < dVal2);
                            case ValidationOperator.LessThanEqual: return (dVal1 <= dVal2);
                        }
                        break;
                    case ValidationDataType.Decimal:
                        decimal nVal1 = decimal.Parse(propValue1);
                        decimal nVal2 = decimal.Parse(propValue2);

                        switch (Operator)
                        {
                            case ValidationOperator.Equal: return nVal1.Equals(nVal2);
                            case ValidationOperator.NotEqual: return !nVal1.Equals(nVal2);
                            case ValidationOperator.GreaterThan: return (nVal1 > nVal2);
                            case ValidationOperator.GreaterThanEqual: return (nVal1 >= nVal2);
                            case ValidationOperator.LessThan: return (nVal1 < nVal2);
                            case ValidationOperator.LessThanEqual: return (nVal1 <= nVal2);
                        }
                        break;
                    case ValidationDataType.Date:
                        DateTime tVal1 = DateTime.Parse(propValue1);
                        DateTime tVal2 = DateTime.Parse(propValue2);

                        switch (Operator)
                        {
                            case ValidationOperator.Equal: return tVal1.Equals(tVal2);
                            case ValidationOperator.NotEqual: return !tVal1.Equals(tVal2);
                            case ValidationOperator.GreaterThan: return (tVal1 > tVal2);
                            case ValidationOperator.GreaterThanEqual: return (tVal1 >= tVal2);
                            case ValidationOperator.LessThan: return (tVal1 < tVal2);
                            case ValidationOperator.LessThanEqual: return (tVal1 <= tVal2);
                        }
                        break;
                }
                return false;
            }
            catch { return false; }
        }
    }
}
